package com.fin.zw.aiqas.service;

import com.fin.zw.aiqas.entity.ConverseRule;
import com.fin.zw.aiqas.entity.InspectionDetail;
import com.fin.zw.aiqas.entity.ReviewTask;
import com.fin.zw.aiqas.entity.RuleInfo;
import com.fin.zw.aiqas.enums.*;
import com.fin.zw.aiqas.mapper.RuleStatisticsMapper;
import com.fin.zw.aiqas.model.component.RuleHitDetails;
import com.fin.zw.aiqas.model.component.RuleHitStatistics;
import com.fin.zw.aiqas.model.data.ResultDetailModel;
import com.fin.zw.aiqas.model.request.ApprovalRequest;
import com.fin.zw.aiqas.model.response.ReconsiderResponse;
import com.fin.zw.aiqas.model.session.SessionModel;
import com.fin.zw.aiqas.repository.InspectionDetailRepository;
import com.fin.zw.aiqas.repository.ReviewTaskRepository;
import com.fin.zw.aiqas.repository.RuleInfoRepository;
import com.fin.zw.aiqas.repository.UserInfoRepository;
import com.fin.zw.aiqas.util.BadRequestException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.ListUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service("reconsiderationReviewService")
public class ReconsiderationReviewService {

    private final static Logger log = LoggerFactory.getLogger(ReconsiderationReviewService.class);

    @Autowired
    InspectionDetailRepository inspectionDetailRepository;//质检结果详情表

    @Autowired
    private UserInfoRepository userInfoRepository; //用户表

    @Autowired
    private ReviewTaskRepository reviewTaskRepository;

    @Autowired
    private ConverseRuleService converseRuleService;

    @Autowired
    private RuleStatisticsMapper ruleStatisticsMapper;

    @Autowired
    private RuleInfoRepository ruleInfoRepository;

    /**
     * 查询待审批详情
     *
     * @param
     * @return
     */
    public ReconsiderResponse queryReconsideration(Long detailId) {
        log.info("根据质检详情ID[{}]查询质检结果详情!", detailId);
        ResultDetailModel detail = ruleStatisticsMapper.queryDetails(detailId);
        log.info("统计命中结果的所有规则");
        List<RuleHitDetails> hitRule = new ArrayList<>();
        log.info("读取每一句话的相关信息");
        detail.getConverseModelList().forEach(con -> {
            con.getConverseRuleSet().forEach(rule -> {
                hitRule.add(new RuleHitDetails(detailId,con.getConverseId(),rule.getConRuleId(),
                        rule.getRuleId(),rule.getRuleName(),rule.getHandReconsiderState(),rule.getDetectionType()));
            });
        });
        Map<Long, RuleHitStatistics> tempMap = new HashMap<>();
        hitRule.forEach(e -> {
            if (!tempMap.containsKey(e.getRuleId())) {
                tempMap.put(e.getRuleId(), new RuleHitStatistics(e.getRuleId(), e.getRuleName(), 1));
            } else {
                RuleHitStatistics temp_statistics = tempMap.get(e.getRuleId());
                temp_statistics.setCountSum(temp_statistics.getCountSum() + 1);
            }
        });
        Set<RuleHitStatistics> ruleHitSet = tempMap.values().stream().collect(Collectors.toSet());
        ReconsiderResponse response = new ReconsiderResponse();
        BeanUtils.copyProperties(detail, response.getOverview());
        response.setRuleHitDetails(hitRule);//保存命中结果详情
        response.setScenesId(detail.getScenesId());
        response.setConverseList(detail.getConverseModelList());//将结果文本结果保存在结果对象中
        response.setRuleHitSet(ruleHitSet);//规则命中统计信息
        response.setReviewContent(detail.getReviewContent());//复核意见
        response.setReasons(detail.getReasons());//复议申请原因
        response.setOpinion(detail.getOpinion());//复议审批意见
        return response;
    }

    /**
     * 复合,复议公用审批
     *
     * @param request
     * @param sessionModel
     */
    public void Approval(ApprovalRequest request, SessionModel sessionModel) {
        InspectionDetail detail = inspectionDetailRepository.findById(request.getInspectionId()).orElseThrow(() -> new BadRequestException("", "质检结果详情未查询到"));
        ReviewTask reviewTask = detail.getReviewTask();
        List<ConverseRule> converseRuleList = new ArrayList<>();//更新的，主要是机器检测有问题的数据
        if (StringUtils.isBlank(request.getApprovalType())) {
            throw new BadRequestException("", "审批类型不能为空!!!");
        } else if ("FH_APPROVAL".equals(request.getApprovalType())) {
            log.info("开始复核任务.......");
            log.info("复核意见----->" + request.getReviewContent());
            detail.setReviewContent(request.getReviewContent());//复核备注
            detail.setReviewStatus(ReviewStatus.HAVE_REVIEW);//复核状态
            detail.setReviewDate(new Date());//复核时间
            //当前明细复核完毕给对应复核任务完成数量 +1
            reviewTask.setReviewTaskFinishNum(reviewTask.getReviewTaskFinishNum() + 1);
            reviewTask.setUpdateUserId(sessionModel.getUserId());
            reviewTask.setUpdateRealName(sessionModel.getUserName());
            reviewTask.setUpdateTime(new Date());
            if (reviewTask.getReviewTaskFinishNum() == reviewTask.getReviewTaskNum()) {
                reviewTask.setReviewTaskStatus(ReviewTaskStatus.REVIEW_OVER);
            }
            reviewTaskRepository.save(reviewTask);
            //更新人工复检的规则命中状态
            List<ConverseRule> addConverseRules = new ArrayList<>();//机器没有检测出，人为添加进去的
            request.getHandVerifyModels().forEach(handVerifyModel -> {
                if (handVerifyModel.getCovRuleId() != null
                        && handVerifyModel.getDetectionType().toString().equals(DetectionType.ROBOT.toString())) {
                    ConverseRule converseRule = converseRuleService.findById(handVerifyModel.getCovRuleId());
                    converseRule.setHandReconsiderState(handVerifyModel.getInspectionResult());
                    converseRuleList.add(converseRule);
                } else {
                    if (handVerifyModel.getDetectionType().toString().equals(DetectionType.MANUAL.toString()) //人工添加的
                            && handVerifyModel.getRuleId() != null) {
                        ConverseRule converseRule = new ConverseRule();
                        converseRule.setConverseId(handVerifyModel.getConverseId());
                        RuleInfo ruleInfo = ruleInfoRepository.findById(handVerifyModel.getRuleId()).orElseThrow(() -> new BadRequestException("", "没有查询对应的规则信息！"));
                        converseRule.setRuleInfo(ruleInfo);
                        converseRule.setHandReconsiderState(HitStatus.HIT);
                        converseRule.setDetectionType(handVerifyModel.getDetectionType());
                        addConverseRules.add(converseRule);
                    }
                }
            });
            if (!ListUtils.isEmpty(addConverseRules)) {
                converseRuleService.saveAll(converseRuleList);
            }
            log.info("复核完成!!!!!!");
        } else if ("FY_APPLY".equals(request.getApprovalType())) {//复议申请
            log.info("对质检结果发起复议申请.......");
            log.info("复议申请原因----->" + request.getReasons());
            detail.setReasons(request.getReasons());
            detail.setReconsiderStatus(ApproveStatus.PENDING);//待审批
            detail.setApplyUser(userInfoRepository.findById(sessionModel.getUserId()).get());
            detail.setApplyTime(new Date());
            log.info("复议申请完成!!!!!!");
        } else if ("FY_APPROVAL".equals(request.getApprovalType())) {//复议审批
            log.info("开始审批复议.......");
            log.info("复议审批意见----->" + request.getOpinion());
            detail.setReconsiderStatus(ApproveStatus.FINISH);
            detail.setReconsiderDate(new Date());
            detail.setOpinion(request.getOpinion());
            detail.setReconsiderUserInfo(userInfoRepository.findById(sessionModel.getUserId()).get());
            //更新人工复检的规则命中状态
            request.getHandVerifyModels().forEach(handVerifyModel -> {
                ConverseRule converseRule = converseRuleService.findById(handVerifyModel.getCovRuleId());
                converseRule.setHandReconsiderState(handVerifyModel.getInspectionResult());
                converseRuleList.add(converseRule);
            });
            log.info("复议审批完成!!!!!!");
        } else {
            log.error("复合-复议审批中不支持的类型........" + request.getApprovalType());
        }
        inspectionDetailRepository.save(detail);
        converseRuleService.saveAll(converseRuleList);

    }
}
